CO2 Emissions Infographics¶

Two case studies one with a single image the other with multiple images and text

Import the libraries

In [ ]:
import pandas as pd
import matplotlib.pyplot as plt

imagepath = "images/"

Get the data¶

The data includes various climate indicators for a number of countries and regions (entities). We will be using the CO2 Concentrations data for the World as a whole

co2 is the dataframe that contains all of the data

co2world contains the data for the World entity

In [ ]:
# Read the data

# original source: https://ourworldindata.org/co2-and-other-greenhouse-gas-emissions

co2 = pd.read_csv('data/climate-change.csv')

co2world = co2[co2['Entity']=='World']
co2world
Out[ ]:
Entity Year CO2 concentrations CH4 concentrations N2O concentrations February September Mass U.S. glaciers CSIRO IAP MRIJMA NOAA Snow cover Sea surface temp Sea surface temp (lower-bound) Sea surface temp (upper-bound) IAP.1 NOAA.1 MRIJMA.1 Arctic sea ice
847 World -803720 207.285440 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
848 World -803183 202.226839 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
849 World -802574 204.861938 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
850 World -802061 207.498645 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
851 World -801976 202.921723 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2774 World 2018 408.520833 1857.422500 330.914167 NaN NaN NaN NaN 17.630567 16.642667 16.485767 NaN 0.61641 0.59350 0.63888 25.426967 22.427733 26.827333 4.79
2775 World 2019 411.419167 1866.669167 331.886667 NaN NaN NaN NaN 18.933567 17.872667 17.489767 NaN 0.71702 0.69317 0.73946 27.445967 NaN 28.777333 4.36
2776 World 2020 413.943333 1879.103333 333.038333 NaN NaN NaN NaN 20.007567 18.082667 17.287767 NaN 0.70991 0.68467 0.73446 29.420967 NaN 29.277333 4.00
2777 World 2021 416.106667 1895.455833 334.322500 NaN NaN NaN NaN NaN NaN NaN NaN 0.63219 0.60608 0.65442 NaN NaN NaN 4.92
2778 World 2022 417.652857 1908.336667 335.406667 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

1932 rows × 20 columns

Plot the World CO2 Concentrations¶

Set the ticks and labels so that it is more readable and define the x- and y-axis labels

Save the resulting figure as an image

In [ ]:
co2world.plot(y="CO2 concentrations", x='Year', grid = True, figsize=(20,10))
plt.xticks([-800000, -600000, -400000, -200000, 0], ['800,000 BCE', '600,000 BCE', '400,000 BCE', '200,000 BCE','0'],
       rotation=20)
plt.ylabel("carbon dioxode level (parts per million)")
plt.xlabel("years before today (0 = 1950)")
plt.savefig(f'{imagepath}co2world.png')
plt.legend("")
plt.title("CO2 Concentrations")
#co2world.tail(75)
Out[ ]:
Text(0.5, 1.0, 'CO2 Concentrations')

Add an image¶

Code as before but now read in an image and display that with alpha setting 0.5 so it is in the bacjground

original image from NASA: https://www.nasa.gov/mission_pages/station/images/index.html

The result is a graph that contains the image - for an infographic we want the chart to be inside the boundaries of the image

So this is not the approach to take

In [ ]:
ax = co2world.plot(y="CO2 concentrations", x='Year', grid = True, figsize=(20,10))
plt.xticks([-800000, -600000, -400000, -200000, 0], ['800,000 BCE', '600,000 BCE', '400,000 BCE', '200,000 BCE','0'],
       rotation=20)
plt.ylabel("carbon dioxode level (parts per million)")
plt.xlabel("years before today (0 = 1950)")
plt.legend("")
plt.title("CO2 Concentrations")
bground=plt.imread(f'{imagepath}ISS_earth.en.jpg')
ax.imshow(bground, aspect='auto', alpha=0.5, extent=(-800000,20000,100,500))
plt.show()

Set up chart to look like NASA image¶

We want the the infographic to look like this:

Original image: https://climate.nasa.gov/climate_resources/24/graphic-the-relentless-rise-of-carbon-dioxide/

So we change the original chart to add annotations

Save as image

In [ ]:
color = 'darkblue'
fontsize = 24

ax = co2world.plot(y="CO2 concentrations", x='Year', linewidth= 2, color = 'darkred',grid = True, figsize=(20,10))
plt.xticks([-800000, -600000, -400000, -200000, 0], 
                ['800,000 BCE', '600,000 BCE', '400,000 BCE', '200,000 BCE','0',], color = color, fontsize = fontsize)
plt.yticks(color = color,fontsize=fontsize)
plt.ylabel("carbon dioxode level (parts per million)",fontsize=fontsize, color =color)
plt.xlabel("years before today (0 = 1950)",fontsize=fontsize, color =color)
plt.savefig(f'{imagepath}co2world.png')
plt.legend("")
plt.title("CO2 Concentrations", weight='bold', fontsize=fontsize, color = color)

caption = "For millenia, atmospheric carbon has never been above this line "
plt.text(-790000,320, caption,
        verticalalignment='top', horizontalalignment='left', fontsize=fontsize, color = color)

plt.plot([-800000,0],[305,305], linestyle = 'dashed', color='red', linewidth = 2)
plt.annotate("1950",xy = (0,312), xytext = (70000,306),
                arrowprops=dict(facecolor= color, shrink=0.1), fontsize=fontsize, color = color)
plt.annotate("2022",xy = (0,417), xytext = (70000,411),
                arrowprops=dict(facecolor= color, shrink=0.1), fontsize=fontsize, color = color)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)

plt.savefig(f'{imagepath}co2.png', transparent = True)
plt.show()

Create the infographic¶

The graph now looks like the one in the NASA image

Create a dummy chart 100x100, set alpha to 0 so it is invisible

imshow both images

  • set the back extent to the whole chart, the chart image to slightly less
  • set the alpha of background to 0.3 so the graph shows up
  • switch off the axis
In [ ]:
fig, ax = plt.subplots(figsize=(20,10), layout = 'constrained')

ax.plot([0,100],[0,100], alpha = 0)
bground=plt.imread(f'{imagepath}ISS_earth.en.jpg')

img1 = plt.imread(f'{imagepath}co2.png')
ax.imshow(img1, aspect='auto', alpha=1, extent=(1,99,1,99))

ax.imshow(bground, aspect='auto', alpha=0.3, extent=(0,100,0,100))

plt.axis('off')
Out[ ]:
(0.0, 100.0, 0.0, 100.0)
In [ ]:
# original source: https://github.com/owid/co2-data

co2 = pd.read_csv('data/owid-co2-data.csv')
co2
countries = co2.country.unique()
countries
continents = ['Europe','North America','South America','Asia','Oceania']
co2continents = co2[co2['country'].isin(continents)]

fig, ax = plt.subplots()
#ax = None
for c in continents:
    ax = co2continents[co2continents['country']== c].plot(y='co2',x='year', label = c, linewidth  = 2, ax = ax)
plt.savefig(f'{imagepath}co2Continents.png')
plt.show()
In [ ]:
fig, ax = plt.subplots(figsize=(15,10), layout = 'constrained')


img1 = plt.imread(f'{imagepath}co2Continents.png')
img2 = plt.imread(f'{imagepath}co2.png')
bground = plt.imread(f'{imagepath}ISS_earth.en.jpg')


title = """
CO2 Emissions
"""
text1 = """
CO2 emissions have risen 
significantly in all parts 
of the World in modern times,
particulary in Asia.
"""
text2 = """
For hundreds of millenia,
CO2 levels never rose above 
around 300ppm. In 1950 it 
was just over 300 and now it 
is over 400ppm
"""

# Create a figure that we can use as a canvas
ax.plot([0,100],[0,100], alpha = 0)


# Place the images on the canvas
ax.imshow(img1, aspect='auto', alpha=1, extent=(40,98,50,98))
ax.imshow(img2, aspect='auto', alpha=1, extent=(2,60,2,50))
ax.imshow(bground, aspect='auto', alpha=0.3, extent=(0,100,0,100))

# Add text to the canvas
ax.text(5,95, title,
        verticalalignment='top', horizontalalignment='left',
        color='red', fontsize=36, weight = 'bold')
ax.text(5,80, text1,
        verticalalignment='top', horizontalalignment='left',
        color='black', fontsize=18)
ax.text(65,40, text2,
        verticalalignment='top', horizontalalignment='left',
        color='black', fontsize=18)

# Switch off the ticks and bounding frame
plt.axis('off')


plt.savefig(f'{imagepath}CO2-info-graphic.png')